﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.UI;
using KDS.Mes.Authorization;
using KDS.Mes.Dto;
using KDS.Mes.Mes.Cartypes;
using KDS.Mes.Mes.Styles.Dtos;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace KDS.Mes.Mes.Styles
{
    /// <summary>
    /// 款式信息服务实现
    /// </summary>
    [AbpAuthorize(AppPermissions.Pages_Bom_Styles)]
    public class StyleAppService : MesAppServiceBase, IStyleAppService
    {
        private readonly IRepository<Style, int> _styleRepository;
        private readonly IStyleListExcelExporter _styleListExcelExporter;
        private readonly StyleManage _styleManage;
        private readonly IRepository<Cartype, int> _cartypeRepository;

        /// <summary>
        /// 构造方法
        /// </summary>
        public StyleAppService(
            IRepository<Style, int> styleRepository,
            StyleManage styleManage, 
            IStyleListExcelExporter styleListExcelExporter,
            IRepository<Cartype, int> cartypeRepository
  )
        {
            _styleRepository = styleRepository;
            _styleManage = styleManage;
            _styleListExcelExporter = styleListExcelExporter;
            _cartypeRepository = cartypeRepository;
        }

        #region 款式信息管理

        public async Task<ListResultDto<StyleListDto>> Getstyles(GetStyleInput input)
        {
            var styles = await _styleRepository.GetAll()
                .ToListAsync();

            return new ListResultDto<StyleListDto>(styles.MapTo<List<StyleListDto>>());
        }
        /// <summary>
        /// 根据CartypeId获取对应的Styles
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public List<ComboboxItemDto> GetAllStyleByCartypeId(NullableIdDto<int> input)
        {
            List<ComboboxItemDto> output = new List<ComboboxItemDto>();
            var query = _styleRepository.GetAll()
                .WhereIf(input.Id.HasValue, u => u.CartypeId == input.Id).ToList();
            //query = query
            output = query
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.StyleName))
               .ToList();
            return output;
        }

        public PagedResultDto<StyleListDto> GetPagedStyles(GetStyleInput input)
        {
            //初步过滤
            var query = _styleRepository.GetAll();
            //排序
            query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(x => x.Id) : query.OrderByDescending(t => t.CreationTime);
            //获取总数
            var tasksCount = query.Count();
            //默认的分页方式
            //ABP提供了扩展方法PageBy分页方式
            var taskList = query.PageBy(input).ToList();

            return new PagedResultDto<StyleListDto>(tasksCount, taskList.MapTo<List<StyleListDto>>());
        }

        /// <summary>
        /// 根据查询条件获取款式信息分页列表
        /// </summary>
        public async Task<PagedResultDto<StyleListDto>> GetPagedStylesAsync(GetStyleInput input)
        {
            var query = _styleRepository.GetAll();
            //TODO:根据传入的参数添加过滤条件

            var styleCount = await query.CountAsync();

            var styles = await query
            .OrderBy(input.Sorting)
            .PageBy(input)
            .ToListAsync();

            var styleListDtos = styles.MapTo<List<StyleListDto>>();
            return new PagedResultDto<StyleListDto>(
            styleCount,
            styleListDtos
            );
        }

        /// <summary>
        /// 通过Id获取款式信息信息进行编辑或修改
        /// </summary>
        public async Task<GetStyleForEditOutput> GetStyleForEditAsync(NullableIdDto<int> input)
        {
            var output = new GetStyleForEditOutput();

            StyleEditDto styleEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _styleRepository.GetAsync(input.Id.Value);
                styleEditDto = entity.MapTo<StyleEditDto>();
            }
            else
            {
                styleEditDto = new StyleEditDto();
            }

            output.Style = styleEditDto;
            output.Cartypes = _cartypeRepository.GetAllList()
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.CartypeName) { IsSelected = output.Style.CartypeId == c.Id })
               .ToList();
            return output;
        }

        /// <summary>
        /// 通过指定id获取款式信息ListDto信息
        /// </summary>
        public async Task<StyleListDto> GetStyleByIdAsync(EntityDto<int> input)
        {
            var entity = await _styleRepository.GetAsync(input.Id);

            return entity.MapTo<StyleListDto>();
        }

        /// <summary>
        /// 新增或更改款式信息
        /// </summary>
        public async Task CreateOrUpdateStyleAsync(CreateOrUpdateStyleInput input)
        {
            if (input.StyleEditDto.Id.HasValue)
            {
                await UpdateStyleAsync(input.StyleEditDto);
            }
            else
            {
                await CreateStyleAsync(input.StyleEditDto);
            }
        }

        /// <summary>
        /// 新增款式信息
        /// </summary>

        [AbpAuthorize(AppPermissions.Pages_Bom_Styles_Create)]
        public virtual async Task<StyleEditDto> CreateStyleAsync(StyleEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增
            await CheckStyleIfAlreadyExists(input.StyleName, input.Id);
            var entity = input.MapTo<Style>();

            entity = await _styleRepository.InsertAsync(entity);
            return entity.MapTo<StyleEditDto>();
        }

        /// <summary>
        /// 编辑款式信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_Styles_Edit)]
        public virtual async Task UpdateStyleAsync(StyleEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新
            await CheckStyleIfAlreadyExists(input.StyleName,input.Id);
            var entity = await _styleRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _styleRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除款式信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_Styles_Delete)]
        public async Task DeleteStyleAsync(EntityDto<int> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _styleRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除款式信息
        /// </summary>
        [AbpAuthorize(AppPermissions.Pages_Bom_Styles_Delete)]
        public async Task BatchDeleteStyleAsync(List<int> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _styleRepository.DeleteAsync(s => input.Contains(s.Id));
        }
        private async Task CheckStyleIfAlreadyExists(string styleName, int? id = null)
        {
            var existingStyle = await _styleRepository.GetAll()
                .FirstOrDefaultAsync(l => l.StyleName == styleName);
            if (existingStyle == null)
            {
                return;
            }

            if (id != null && existingStyle.Id == id)
            {
                return;
            }

            throw new UserFriendlyException(L("ThisStyleAlreadyExists"));
            
        }

        #endregion 款式信息管理

        #region 款式信息的Excel导出功能

        public async Task<FileDto> GetStyleToExcel()
        {
            var entities = await _styleRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<StyleListDto>>();

            var fileDto = _styleListExcelExporter.ExportStyleToFile(dtos);

            return fileDto;
        }

        #endregion 款式信息的Excel导出功能
    }
}